use std::fmt;



/// A trait which handles errors reported by the `ManageConnection`.
pub trait HandleError<E>: std::fmt::Debug + Send + Sync + 'static {
    /// Handles an error.
    fn handle_error(&self, error: E);
}

/// A `HandleError` implementation which does nothing.
#[derive(Copy, Clone, Debug)]
pub struct NopErrorHandler;

impl<E> HandleError<E> for NopErrorHandler {
    fn handle_error(&self, _: E) {}
}

/// A `HandleError` implementation which logs at the error level.
#[derive(Copy, Clone, Debug)]
pub struct LoggingErrorHandler;

impl<E> HandleError<E> for LoggingErrorHandler
where
    E: std::error::Error,
{
    fn handle_error(&self, error: E) {
        error!("{}", error);
    }
}



/// The error type returned by methods in this crate.
#[derive(Debug)]
pub struct Error(pub Option<String>);

impl fmt::Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str("timed out waiting for connection")?;
        if let Some(ref err) = self.0 {
            write!(fmt, ": {}", err)?;
        }
        Ok(())
    }
}

impl std::error::Error for Error {}
